home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Arsenal
/
OS2 Arsenal v1.0 (Disc 2)(Arsenal Computer).ISO
/
os2_inet
/
progcsd.exe
/
READH32.ME
< prev
next >
Wrap
Text File
|
1992-11-13
|
8KB
|
224 lines
TCPH32 PACKAGE
User Documentation
John McGarvey 11/13/92
These C header files provided for the TCP/IP for OS/2 programmer's toolkit
are intended for use with Microsoft C 6.0 and IBM C Set/2. This version is
being made publicly available to customers as a CSD for the toolkit.
32 bit TCP/IP OS/2 applications can be created with C Set/2 using this
package. Such applications can call these 16 bit dynamic link libraries:
TCPIPDLL.DLL
RPCDLL.DLL
FAPIDLL.DLL (new with this package).
32 bit applications can call all sockets, FTP, and RPC APIs. SNMP DPI and
the Kerberos and NCS APIs have not been enabled for 32 bit applications.
To use this package, you must first install the TCP/IP for OS/2
Programmer's Toolkit. If this package was obtained as a CSD for that
toolkit, it is installed using the standard procedure for CSDs. If
it was obtained as a ZIP file from CompuServe, or via FTP from
software.watson.ibm.com, it should be unpacked using the command:
pkunzip -d tcph32.zip d:\
where d: is the drive on which OS/2 tcpip has been installed.
This will replace some of the header files in the programmer's toolkit
with new files that are compatible with C Set/2. The new header files
can also be used with Microsoft C 6.0 to create 16 bit applications.
Applications created to call the existing DLLs will continue to work with
future releases of TCP/IP for OS/2, as these DLLs will still be shipped.
32 bit applications using this package will still call 16 bit DLLs.
A full 32 bit implementation of the TCP/IP APIs is planned.
Now, it would be nice if the programmer did not need to know that her 32
bit application is calling a 16 bit DLL, but unfortunately she does need
to know in some cases, and the source code will differ, in small ways,
from what it would be for true 32 bit APIs. Here are some examples:
/* Wrong: int sockets[3]; Right: */
short sockets[3];
select(sockets,1,1,1,5000);
The 16 bit DLLs expect 16 bit integers, whereas an int is 32 bits wide in
C Set/2. Therefore it is important to use short instead of int. Note
also that a full 32 bit implementation of select() would require int
instead of short.
This call traps:
printf("%s",inet_ntoa(in));
This call works:
printf("%s",(char *)inet_ntoa(in));
This is because inet_ntoa returns a char * _Seg16, and not a char *, so the
cast is necessary to tell the compiler to "thunk", that is, to convert from
a 16:16 pointer to a 0:32 pointer. In most cases, C Set/2 will give
compiler errors if you try to pass the wrong kind of pointer or if you
provide a function with the wrong linkage type. The printf() example above
is an exception, because C Set/2 does not know what type is expected as a
parameter to printf().
Always use /NOI in linking to the TCP/IP DLLs, as the entry points are
lower case. Compile with the /Sp1 or /Sp2 switch. This switch is needed
because, by default, C Set/2 aligns structure members on four byte
boundaries, whereas 16 bit compilers align on 2 byte boundaries. Link
with one or more of the libraries tcpipdll.lib, fapidll.lib, and
rpcdll.lib.
Please report any problems with this package by calling customer support:
support number: 1-800-237-5511
TCP/IP component ID: 5798RXW00
Help can also be obtained by submitting questions to OS2TCPIP CFORUM
on IBMLINK, or use "go OS2DF2" (section 5 is TCP/IP) on CompuServe.
Addendum: Creating 32 bit RPC applications
One can create 32 bit RPC applications that call the 16 bit APIs, but it
requires special attention to issues of mixed model programming. 32 bit
RPC programs that call the 16 bit RPCDLL.DLL will typically have callbacks,
i.e. the 16 bit code must call the 32 bit code. So, the 32 bit code must
provide a 16 bit entry point. This can be done as follows:
void _Far16 _Cdecl dumytcpprog( struct svc_req * _Seg16 rqstp_t,
SVCXPRT * _Seg16 transp_t) {
// whatever
}
SVCXPRT transp_t;
svc_register(transp_t,30000,1,dumytcpprog,0);
The _Far16 _Cdecl tells C Set/2 to create a 16 bit entry point, and the
_Seg16 qualifiers tell the code to expect 16:16 pointers to be passed as
parameters. These statements are needed to create an entry point the 16
bit RPCDLL.DLL can call as a result of svc_register().
Take special care when passing pointers to pointers as parameters in
function calls. Here is an example:
char *psza,*pszb,*hostname;
char * _Seg16 psz16a, * _Seg16 psz16b;
psza="sample string";
pszb=(char *)malloc(500);
psz16a=psza;
psz16b=pszb;
hostname="thishost";
error = callrpc(hostname,ARRAYRCVPROG,VERSION,ARRAYRCVPROC,
xdr_wrapstring,(char *)&psz16a,xdr_wrapstring,(char *)&psz16b);
The compiler will convert the pointer to hostname correctly, as the
prototype for callrpc() tells it what to do. Also, it will correctly
pass 16 bit pointers to psz16a, psz16b, and the function xdr_wrapstring.
But if psz16a and psz16b are not themselves 16 bit pointers, the
compiler will not know to convert them. A working example is given
below.
client.c
/* LICENSED MATERIALS - PROPERTY OF IBM */
/* THIS PRODUCT CONTAINS "RESTRICTED MATERIALS OF IBM" */
/* 5685-061 (C) COPYRIGHT IBM CORP. 1989 */
/* ALL RIGHTS RESERVED. */
/* US Government Users Restricted Rights - */
/* Use, duplication or disclosure restricted */
/* by GSA ADP Schedule Contract with IBM Corp. */
/* SEE COPYRIGHT INSTRUCTIONS, G120-2083 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <rpc\rpctypes.h>
#include <rpc\rpc.h>
#include <sys\socket.h>
#include <netdb.h>
#include <rpc\pmap_pro.h>
#include <rpc\pmap_cln.h>
int main(int argc, char **argv)
{
enum clnt_stat error;
char *argg;
char *argh;
char * _Seg16 argg16;
char * _Seg16 argv216;
argg= malloc(1000);
argh = malloc(1000);
argg16=argg;
argv216=argv[2];
if (argc != 3) {
fprintf(stderr,"usage: arraysnd hostname word\n");
exit (-1);
} /* endif */
strcpy(argh, argv[2]);
printf("before callrpc\n");
error = callrpc(argv[1],ARRAYRCVPROG,VERSION,ARRAYRCVPROC,
xdr_wrapstring,(char *)&argv216,xdr_wrapstring,(char *)&argg16);
printf("error=%d\n",error);
if (error != RPC_SUCCESS) {
clnt_perrno(error);
exit(1);
} /* endif */
printf("test :%s value sent: %s value received: %s\n",argv[2],argh,argg);
exit(0);
}
server.c
/* LICENSED MATERIALS - PROPERTY OF IBM */
/* THIS PRODUCT CONTAINS "RESTRICTED MATERIALS OF IBM" */
/* 5685-061 (C) COPYRIGHT IBM CORP. 1989 */
/* ALL RIGHTS RESERVED. */
/* US Government Users Restricted Rights - */
/* Use, duplication or disclosure restricted */
/* by GSA ADP Schedule Contract with IBM Corp. */
/* SEE COPYRIGHT INSTRUCTIONS, G120-2083 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <rpc\rpctypes.h>
#include <rpc\rpc.h>
#include <sys\socket.h>
#include <netdb.h>
#include <rpc\pmap_pro.h>
#include <rpc\pmap_cln.h>
void * _Seg16 _Far16 _Cdecl arrayrcv(char * _Seg16 * _Seg16 in)
{
char *out;
printf("array received: %s\n",(char *)*in);
out = *in;
printf("array being returned: %s\n",out);
return (in);
}
int main(int argc,char **argv) {
registerrpc(ARRAYRCVPROG,VERSION,ARRAYRCVPROC,arrayrcv,xdr_wrapstring,
xdr_wrapstring);
printf("Arrayrcv Registration with Port Mapper completed\n");
svc_run();
printf("Error:svc_run returned!\n");
return 0;
}